package com.ys.filelib.filedialog.ftp;

import com.ys.filelib.filedialog.FileInfo;
import com.ys.filelib.filedialog.common.IDownloadListener;
import com.ys.filelib.filedialog.entity.FTPFileBean;
import com.ys.filelib.filedialog.loader.Executor;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * FTP帮助类，对云盘文件进行操作：增、删、改、查
 */
public class FTPDriveHelper {

    private FTPHelper mFtpHelper;
    private boolean mStopDownload;

    public FTPDriveHelper(FTPHelper helper) {
        this.mFtpHelper = helper;
    }

    public void setFtpHelper(FTPHelper ftpHelper) {
        this.mFtpHelper = ftpHelper;
    }

    public FTPHelper getFtpHelper() {
        return mFtpHelper;
    }

    /**
     * 下载FTP文件
     * @param path 文件保存目录(文件夹)
     */
    public void downloadFile(FTPFileBean file, String path, IDownloadListener listener) {
        Executor.execute(()-> {
            try {
                File local = new File(path, file.getName());
                if (local.exists() && local.length() == file.getSize()) {
                    listener.onSuccess(local.getPath());
                } else {
                    doDownloadFile(file, path, listener);
                    mFtpHelper.reconnect();
                }
            } catch (Exception e) {
                e.printStackTrace();
                listener.onFailure(e);
            }
        });
    }

    /**
     * 下载FTP文件
     * @param path 文件保存目录(文件夹)
     */
    private void doDownloadFile(FTPFileBean fileBean, String path, IDownloadListener listener) throws Exception {
        mStopDownload = false;
        InputStream input = null;
        FileOutputStream output = null;
        try {
            FTPClient client = mFtpHelper.getFtpClient();
            input = client.retrieveFileStream(fileBean.getPath());
            if (input == null) {
                mFtpHelper.connect();
                input = client.retrieveFileStream(fileBean.getPath());
            }
            String savePath = path + "/" + fileBean.getName();
            output = new FileOutputStream(savePath);
            int len;
            long progress = 0;
            long fileSize = fileBean.getSize();
            byte[] buff = new byte[512000];
            while ((len = input.read(buff)) != -1) {
                progress += len;
                output.write(buff, 0, len);
                listener.onProgress(progress, (int) (progress * 100 / fileSize));
                if (mStopDownload) {
                    break;
                }
            }
            output.flush();
            if (mStopDownload) {
                listener.onStop();
                new File(savePath).delete();
            } else {
                listener.onSuccess(savePath);
            }
            System.out.println("=============download success");
        } finally {
            closeQuietly(output);
            closeQuietly(input);
        }
    }

    public boolean uploadFile(File file, String pathname) {
        try {
            FTPClient client = mFtpHelper.getFtpClient();
            OutputStream output = client.storeFileStream(pathname);
            System.out.println("===========ftpdrive " + output + " " + pathname);
            if (output == null) {
                mFtpHelper.reconnect();
                output = client.storeFileStream(pathname);
            }
            FileInputStream input = new FileInputStream(file);
            int len;
            long current = 0;
            long fileSize = file.length();
            byte[] buff = new byte[512000];
            while ((len = input.read(buff)) != -1) {
                current += len;
                output.write(buff, 0, len);
                //deal.progress = (int) (current * 100 / fileSize);
            }
            output.flush();
            closeQuietly(output);
            closeQuietly(input);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mFtpHelper.reconnect();
        }
        return false;
    }

    public List<FileInfo> listFiles(String dir) {
        FTPFile[] list = mFtpHelper.listFiles(dir);
        if (list == null) {
            mFtpHelper.reconnect();
            list = mFtpHelper.listFiles(dir);
        }
        List<FileInfo> data = new ArrayList<>();
        for(FTPFile file : list) {
            FileInfo fileInfo = new FileInfo();
            fileInfo.ftpFile = new FTPFileBean(file, dir, mFtpHelper.getHost(), mFtpHelper.getPort(), mFtpHelper.getUserName());
            data.add(fileInfo);
        }
        return data;
    }

    private void closeQuietly(Closeable closeable) {
        try {
            if (closeable != null) {
                closeable.close();
            }
        } catch (IOException ioe) {
            // ignore
        }
    }

    public void stopDownload() {
        mStopDownload = true;
    }

    public void exit() {
        Executor.execute(mFtpHelper::disconnect);
    }
}
